package com.ecb.business.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.ecb.business.exception.BusinessException;

import java.util.*;

public class JwtUtils {
    private static final String SECRET_KEY = "epChainBridgeSecretJZGJ";
    private static final long EXPIRATION_TIME = 86400000; // 24小时

//    public static void main(String[] args) {
//        // 创建JWT
//        Map<String, String> info = new HashMap<>();
//        info.put("userName", "用户");
//        info.put("userLoginId", "user123");
//        String jwt = createJwt("subject",info);
//        System.out.println(jwt);
//        // 验证JWT
//        Map<String, String> stringStringMap = decryptToken(jwt, Arrays.asList("userName", "userLoginId"));
//        stringStringMap.forEach((k,v)->{
//            System.out.println(k+":"+v);
//        });
//        if (stringStringMap != null) {
//            System.out.println("JWT验证通过");
//        } else {
//            System.out.println("JWT验证失败");
//        }
//    }


    /**
     * @param subject
     * @param info
     * @return jwt 默认过期时间为24小时
     */
    public static String createJwt(String subject, Map<String, String> info) {
        return createJwtWithExpireTime(subject, info, EXPIRATION_TIME);
    }

    /**
     * @param subject token的subject
     * @param info 要放入token的信息
     * @param expireTime 经过多久后过期，单位毫秒
     * @return jwt
     */
    public static String createJwtWithExpireTime(String subject, Map<String, String> info, long expireTime) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + expireTime);
        return createJwtWithExpireDate(subject, info, expiration);
    }

    /**
     * @param subject token的subject
     * @param info 要放入token的信息
     * @param expireDate token的过期日期
     * @return jwt
     */
    public static String createJwtWithExpireDate(String subject, Map<String, String> info, Date expireDate) {
        Date now = new Date();
        JWTCreator.Builder builder = JWT.create().withSubject(subject);
        for (Map.Entry<String, String> stringStringEntry : info.entrySet()) {
            builder.withClaim(stringStringEntry.getKey(), stringStringEntry.getValue());
        }
        String jwt = builder.withIssuedAt(now)
                .withExpiresAt(expireDate)
                .sign(Algorithm.HMAC256(SECRET_KEY));
        return jwt;
    }

    public static boolean validJwt(String jwt) {
        return decryptToken(jwt, new ArrayList<>()) != null;
    }

    /**
     * @param token
     * @param key 需要获取的key
     * @return key-value
     */
    public static String decryptToken(String token, String key) {
        String res = "";
        try {
            DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(SECRET_KEY))
                    .build()
                    .verify(token);
            Date expiresAt = decodedJWT.getExpiresAt();
            if (expiresAt.before(new Date())) {
                throw new BusinessException("401","token已过期");
            } else {
                    Claim claim = decodedJWT.getClaim(key);
                    res = claim.asString();
            }
            return res;
        } catch (Exception e) {
            // 验证失败，JWT无效
            throw new BusinessException("401","token无效");
        }
    }
    /**
     * @param token
     * @param keyList 需要获取的key
     * @return key-value
     */
    public static Map<String, String> decryptToken(String token, List<String> keyList) {
        Map<String, String> res = new HashMap<>();
        try {
            DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(SECRET_KEY))
                    .build()
                    .verify(token);
            Date expiresAt = decodedJWT.getExpiresAt();
            if (expiresAt.before(new Date())) {
                throw new BusinessException("401","token已过期");
            } else {
                for (String s : keyList) {
                    Claim claim = decodedJWT.getClaim(s);
                    res.put(s, claim.asString());
                }
            }
            return res;
        } catch (Exception e) {
            // 验证失败，JWT无效
                throw new BusinessException("401","token无效");
        }
    }
}